HydroModels Bucket Model Implementation Example
Overview
This document demonstrates the implementation and usage of a hydrological bucket model using the HydroModels framework. The code showcases both single-node and multi-node simulations using the ExpHydro model structure.
Dependencies
using CSV
using DataFrames
using ComponentArrays
using BenchmarkTools
using HydroModels
using ModelingToolkit
Model Configuration
Parameter Setup
The model uses the following parameters for the hydrological simulation:
f
: 0.01674478 (Infiltration parameter)Smax
: 1709.461015 (Maximum soil water storage)Qmax
: 18.46996175 (Maximum discharge)Df
: 2.674548848 (Degree-day factor)Tmax
: 0.175739196 (Maximum temperature threshold)Tmin
: -2.092959084 (Minimum temperature threshold)
Initial States
Initial conditions for the model:
snowpack
: 0.0soilwater
: 1303.004248
Data Input
The model uses time series data from a CSV file located at "data/exphydro/01013500.csv" containing:
- Day length (dayl)
- Mean temperature (tmean)
- Precipitation (prcp)
Implementation Examples
1. Single Node Simulation
# Setup input data
input = (lday=df[ts, "dayl(day)"], temp=df[ts, "tmean(C)"], prcp=df[ts, "prcp(mm/day)"])
solver = HydroModels.ManualSolver{true}()
config = (solver=solver,)
# Convert input to required format
input_arr = Matrix(reduce(hcat, collect(input[ele.meta.inputs]))')
# Run simulation
results = ele(input_arr, pas, config=config, convert_to_ntp=true)
2. Multi-Node Simulation
# Setup for multiple nodes
node_num = 10
node_names = [Symbol(:node, i) for i in 1:node_num]
# Create parameter and state vectors for all nodes
node_params = ComponentVector(NamedTuple{Tuple(node_names)}(repeat([params], length(node_names))))
node_initstates = ComponentVector(NamedTuple{Tuple(node_names)}(repeat([init_states], length(node_names))))
node_pas = ComponentVector(params=node_params, initstates=node_initstates)
# Prepare input data for multiple nodes
input_arr = reduce(hcat, collect(input[HydroModels.get_input_names(ele)]))
node_input = reduce((m1, m2) -> cat(m1, m2, dims=3), repeat([input_arr], length(node_names)))
node_input = permutedims(node_input, (2, 3, 1))
# Run simulation with multiple nodes
run_kwgs = (ptypes=node_names, timeidx=ts)
result = ele(node_input, node_pas, kwargs=run_kwgs)
Model Structure
The model uses a bucket structure defined in exphydro.jl with two main components:
Surface water component (bucket_1):
- Handles precipitation partitioning (rainfall/snowfall)
- Computes potential evapotranspiration
- Manages snowmelt processes
Soil water component:
- Manages soil water storage
- Computes actual evaporation
- Generates baseflow and surface flow
Usage Notes
- The code demonstrates flexibility in handling both single-node and multi-node simulations
- Input data should be properly formatted with required columns (dayl, tmean, prcp)
- Parameters and initial states can be adjusted based on specific catchment characteristics
- The model uses a manual solver for time-stepping
Time Series Processing
The example processes 10,000 time steps (ts = collect(1:10000)) and can be adjusted based on data availability and simulation requirements.